home *** CD-ROM | disk | FTP | other *** search
/ Enter 2004 January / enter-2004-01.iso / files / maxima-5.9.0.exe / {app} / share / maxima / 5.9.0 / src / spgcd.lisp < prev    next >
Encoding:
Text File  |  2003-02-09  |  19.0 KB  |  605 lines

  1. ;;; -*-  Mode: Lisp; Package: Maxima; Syntax: Common-Lisp; Base: 10 -*- ;;;;
  2. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  3. ;;;     The data in this file contains enhancments.                    ;;;;;
  4. ;;;                                                                    ;;;;;
  5. ;;;  Copyright (c) 1984,1987 by William Schelter,University of Texas   ;;;;;
  6. ;;;     All rights reserved                                            ;;;;;
  7. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  8. ;;;   *****************************************************************
  9. ;;;   ***** SPGCD ******* Sparse polynomial routines for GCD **********
  10. ;;;   *****************************************************************
  11. ;;;   ** (C) COPYRIGHT 1982 MASSACHUSETTS INSTITUTE OF TECHNOLOGY *****
  12. ;;;   ****** THIS IS A READ-ONLY FILE! (ALL WRITES RESERVED) **********
  13. ;;;   *****************************************************************
  14. (in-package "MAXIMA")
  15.  
  16. (macsyma-module spgcd)
  17.  
  18. (declare-top (special modulus temp genvar *alpha *which-factor*
  19.           $algebraic algfac* $GCD)
  20.      (mapex t)
  21.      (genprefix spgcd))
  22.  
  23. (load-macsyma-macros ratmac)
  24.  
  25. (defvar *alpha nil) 
  26.  
  27. (defmvar $POINTBOUND *alpha)
  28.  
  29. (defmacro 0? (x) `(= ,x 0))
  30.  
  31. (defmacro melt (a . indices) `(arraycall fixnum ,a . ,indices))
  32.  
  33. (defmacro ARRAYTYPE (m) `(array-type ,m))
  34.  
  35. (defmacro NCOLS (m) `(array-dimension-n ,m 1))
  36.  
  37. (defmacro NROWS (m) `(array-dimension-n ,m 2))
  38.  
  39. (defmacro LEN (lobj) `(cadr ,lobj))
  40.  
  41. (defmacro SKEL (lobj) `(caddr ,lobj))
  42.  
  43. (defmacro MATRIX (lobj) `(cadddr ,lobj))
  44.  
  45. (defmacro CURROW (lobj) `(cadr (cdddr ,lobj)))
  46.  
  47. (defmacro BADROWS (lobj) `(cadr (cddddr ,lobj)))
  48.  
  49.  
  50. (defun PINTERP (x pts vals)
  51.        (do ((u (car vals)
  52.            (pplus u (ptimes
  53.              (pctimes (crecip (pcsubstz (car xk) qk))
  54.                   qk)
  55.              (pdifference (car uk)
  56.                       (pcsubstz (car xk) u)))))
  57.         (uk (cdr vals) (cdr uk))
  58.         (qk (list x 1 1 0 (cminus (car pts)))
  59.         (ptimes qk (list x 1 1 0 (cminus (car xk)))))
  60.         (xk (cdr pts) (cdr xk)))
  61.        ((null xk) u)))
  62.  
  63. (defun PCSUBSTZ (val p)
  64.        (if (pcoefp p) p
  65.        (do ((l (p-terms p) (pt-red l))
  66.         (ans 0
  67.              (ctimes
  68.               (cplus ans (pt-lc l))
  69.               (cexpt val (f- (pt-le l) (pt-le (pt-red l)))))))
  70.            ((null (pt-red l))
  71.         (ctimes
  72.          (cplus ans (pt-lc l))
  73.          (if (0? (pt-le l))
  74.              1
  75.              (cexpt val (pt-le l))))))))
  76.  
  77. ;skeletons consist of list of exponent vectors
  78. ;lifting structures are as follows:
  79.  
  80. ;(matrix <n>            ;length of <skel>
  81. ;        <skel>        ;skeleton of poly being lifted
  82. ;        <matrix>       ; partially diagonalized matrix used to obtain sol.
  83. ;        <row>          ;we have diagonalized this far
  84. ;        <bad rows>)    ; after we get 
  85.  
  86. (defun EVAL-MON (mon pt)
  87.        (do ((l mon (cdr l))
  88.         (ll pt (cdr ll))
  89.         (ans 1 (ctimes
  90.             (if (0? (car l)) 1
  91.             (cexpt (car ll) (car l)))
  92.             ans)))
  93.        ((null l) ans)))
  94.  
  95. ; ONE-STEP causes the  (row,col) element of mat to be made to be zero.  It is
  96. ; assumed that row > col, and that the matrix is diagonal above the row.  
  97. ; n indicates how wide the rows are suppoded to be.
  98.  
  99. (defun ONE-STEP (mat row col n)
  100.        (do ((i col (f1+ i))
  101.         (c (arraycall fixnum mat row col)))    ;Got to save this away before it is 
  102.                     ;zeroed
  103.        ((> i n) mat)
  104.        (store (arraycall fixnum mat row i)
  105.           (cdifference (arraycall fixnum mat row i)
  106.                    (ctimes c (arraycall fixnum mat col i))))))
  107.  
  108. ; MONICIZE-ROW assumes the (row,row) element is non-zero and that this element
  109. ; is to be made equal to one.  It merely divides the entire row by the 
  110. ; (row,row) element.  It is assumed that the (row,n) elements with n < row are
  111. ; already zero.  Again n is the width of the rows.
  112.  
  113. (defun MONICIZE-ROW (mat row n)
  114.        (do ((i n (f1- i))
  115.         (c (CRECIP (arraycall fixnum mat row row))))
  116.        ((= i row)
  117.         (store (arraycall fixnum mat row row) 1))    ;Don't bother doing the
  118.                     ;division on the diagonal
  119.        (store (arraycall fixnum mat row i) (ctimes (arraycall fixnum mat row i) c))))
  120.  
  121. ; FILL-ROW is given a point and the value of the skeleton at the point and
  122. ; fills the apropriate row in the matrix. with the values of the monomials
  123. ; n is the length of the skeleton
  124.  
  125. (defun FILL-ROW (skel mat n row pt val)
  126.        (do ((i 0 (f1+ i))
  127.         (l skel (cdr l)))
  128.        ((= i n)            ;l should be nil now,
  129.         (if (not (null l))        ;but lets check just to make sure
  130.         (merror "Skeleton too long in  FILL-ROW: ~S"
  131.             (list n '= skel)))
  132.         (store (arraycall fixnum mat row n) val))    ;The value is stored in the
  133.                     ;last column
  134.        (store (arraycall fixnum mat row i)
  135.           (eval-mon (car l) pt))))    ;Should think about a better
  136.                     ;way to do this evaluation.
  137.  
  138. (defun SWAP-ROWS (mat m n)        ;Interchange row m and n
  139.        (do ((k 0 (f1+ k))
  140.         (l (ncols mat)))
  141.        ((> k l) mat)
  142.        (store (arraycall fixnum mat m k)
  143.           (prog2 0 (melt mat n k)
  144.              (store (melt mat n k) (melt mat m k))))))
  145.  
  146. ; PARTIAL-DIAG fills in one more row of the matrix and tries to diagonalize
  147. ; what it has so far.  If the row which has just been introduced has a 
  148. ; zero element on the diagonal then it is scanned for its first non-zero
  149. ; element and it is placed in the matrix so that the non-zero element is 
  150. ; on the diagonal.  The rows which are missing are added to the list in 
  151. ; badrows.  The current row pointer may skip a couple of numbers here, so
  152. ; when it is equal to n, the only empty rows to add thing to are on the
  153. ; bad rows list.
  154.  
  155. (defun PARTIAL-DIAG (lobj pt val)    ; Does one step of diagonalization of
  156.    (let ((n (len lobj))        ;the matrix in lobj
  157.      (skel (skel lobj))        
  158.      (mat (matrix lobj))        ;The matrix, obviously
  159.      (row (currow lobj))        ;This is the row which is to be 
  160.                     ;introduced
  161.      (badrows (badrows lobj))    ;Rows which could not be used when
  162.                     ;their time came, and will be used later
  163.      crow)
  164.        (cond ((= row n)            ;All rows already done, must start
  165.                     ;using the rows in badrows.
  166.           (fill-row skel mat n (setq crow (car badrows)) pt val))
  167.          ((fill-row skel mat n row pt val)    ;Fill up the data
  168.           (setq crow row)))
  169.  
  170. ;; This loop kills all the elements in the row up to the diagonal.
  171.  
  172.        (do ((i 0 (f1+ i))        ;runs over the columns of mat
  173.         (l (setq badrows (cons nil badrows)))
  174.         (flag))
  175.        ((= i crow)
  176.         (setq badrows (cdr badrows)))    ;update badrows
  177.        (if (cdr l)            ;Any bad rows around?
  178.            (if (= (cadr l) i)    ;No one for this row,
  179.            (if (and (null flag)    ;So if this guy can fill in
  180.                 (not (0? (melt mat crow i))))
  181.                (progn
  182.             (swap-rows mat crow i)    ;Put this guy in the right spot
  183.             (rplacd l (cddr l))
  184.             (setq flag t crow i))    ; and make him a winner
  185.                (setq l (cdr l)))    ;At any rate this guy isn't 
  186.                     ;used any more.
  187.            (one-step mat crow i n))
  188.            (one-step mat crow i n)))
  189.  
  190.        (if (0? (melt mat crow crow))    ;diagonal is zero?
  191.        (setq badrows (cons crow badrows))
  192.        (progn
  193.         (monicize-row mat crow n)    ;Monicize the diagonal element on this
  194.                     ;row
  195.         (do ((j 0 (f1+ j)))        ;For each element in the rows above 
  196.                     ;this one zero the the crow column
  197.         ((= j crow))        ;Don't zero the diagonal element
  198.         (one-step mat j crow n))))
  199.        (cond ((and (= (f1+ row) n)
  200.            (progn (setq row (f1- row)) t)    ;Decrement it just in case
  201.            (null (cdr badrows)))
  202.           (do ((l nil (cons (melt mat i n) l))
  203.            (i (f1- n) (f1- i)))
  204.           ((< i 0)
  205.            (list 'SOLUTION n skel mat l))))
  206.          (t (list 'MATRIX n skel mat (f1+ row) badrows)))))
  207.  
  208. (defun GEN-POINT (vars)
  209.        (do ((l vars (cdr l))
  210.         (ans nil (cons (cmod (random $POINTBOUND)) ans)))
  211.        ((null l) ans)))
  212.  
  213. ; PDIAG-ALL introduces a new row in each matrix in the list of l-lobjs.
  214. ; The RHS of the equations is stripped off of poly.
  215.  
  216. (defun PDIAG-ALL (l-lobjs poly pt)
  217.        (do ((l l-lobjs (cdr l))
  218.         (lp (p-terms poly))
  219.         (solved t) (c))
  220.        ((null l)
  221.         (if solved (cons 'SOLVED l-lobjs)
  222.         l-lobjs))
  223.        (if (and lp (= (caar l) (pt-le lp)))    ;This term corresponds to the
  224.                     ;current lobj, set c to the coefficient
  225.            (setq c (pt-lc lp) lp (pt-red lp))
  226.            (setq c 0))
  227. ;FIXTHIS                ;Should put it some check for extra 
  228.                     ;terms in the polynomial
  229.        (if (not (eq (cadar l) 'SOLUTION))
  230.            (progn (rplacd (car l)
  231.                   (partial-diag (cdar l) pt c))
  232.               (and solved (null (eq (cadar l) 'SOLUTION)) 
  233.                (setq solved nil))))))
  234.  
  235. ;; not currently called
  236. ;; (defun CREATE-INTVECT (h)
  237. ;;      (do ((l (cdr h) (cddr l))
  238. ;;         (ans nil (cons (list (car l) (cadr l))
  239. ;;                ans)))
  240. ;;        ((null l)
  241. ;;         (nreverse ans))))
  242.  
  243. ;; (defun MERGE-INTVECT (iv h)
  244. ;;      (do ((l iv (cdr l))
  245. ;;         (h (cdr h)))
  246. ;;        ((null l) iv)
  247. ;;        (cond ((or (null h) (> (caar l) (car h)))
  248. ;;           (rplacd (car l) (cons 0 (cdar l))))
  249. ;;          ((= (caar l) (car h))
  250. ;;           (rplacd (car l) (cons (cadr h) (cdar l)))
  251. ;;           (setq h (cddr h)))
  252. ;;          (t (error '|Bad Evaluation point - MERGE-INTVECT|)))))
  253.  
  254.  
  255. (defun MERGE-SKEL (mon poly)
  256.        (cond ((pcoefp poly)
  257.           (list (cons 0 mon)))
  258.          ((do ((l (cdr poly) (cddr l))
  259.            (ans nil
  260.             (cons (cons (car l) mon) ans)))
  261.           ((null l) ans)))))
  262.  
  263. (defun NEW-SKEL (skel polys)
  264.        (list
  265.     (mapcan (fn (mon poly) (merge-skel mon poly))
  266.         skel polys)
  267.     (mapcan (fn (q)
  268.             (cond ((pcoefp q) (list q))
  269.               ((do ((l (cdr q) (cddr l))
  270.                 (ans nil (cons (cadr l) ans)))
  271.                    ((null l) ans)))))
  272.         polys)))
  273.  
  274. (defun CREATE-LOBJS (prev-lift)
  275.   (mapcar #'(lambda (q)
  276.           (let ((n (length (cadr q))))
  277.         (cons (car q)
  278.               (list 'MATRIX n (cadr q)
  279.                 (*array nil 'fixnum n (f1+ n))
  280.                 0 nil))))
  281.       prev-lift))
  282.  
  283. (defun CLEAR-LOBJS (lobjs)
  284.   (mapcar #'(lambda (q)
  285.           (cons (car q)
  286.             (list 'MATRIX (caddr q) (cadddr q)
  287.               (caddr (cddr q)) 0 nil)))
  288.       lobjs))
  289.  
  290. (defun SPARSE-LIFT (c f g l-lobjs vars)
  291.        (do ((pt (gen-point vars) (gen-point vars))
  292.         (gcd))
  293.        ((eq (car l-lobjs) 'SOLVED)
  294.         (cdr l-lobjs))
  295.        (setq gcd (lifting-factors-image
  296.               (pcsub c pt vars) (pcsub f pt vars) (pcsub g pt vars)))
  297.        (if (or (pcoefp gcd)
  298.            (not (= (pt-le (p-terms gcd)) (caar l-lobjs))))
  299.            (throw 'Bad-Point nil)
  300.            (setq l-lobjs (pdiag-all l-lobjs gcd pt)))))
  301.  
  302. (defun LIFTING-FACTORS-IMAGE (c f g)
  303.        (let ((gcd (pgcdu f g)))
  304.         (case *which-factor*
  305.            (1 (pctimes c gcd))
  306.            (2 (pquotient f gcd))
  307.            (3 (pquotient g gcd)))))
  308.  
  309. (defun ZGCD-LIFT* (c f g vars degb)
  310.        (do ((vals (gen-point vars) (gen-point vars))
  311.         (ans))
  312.        ((not (null ans))
  313.         ans)
  314.        (setq ans
  315.          (catch 'Bad-Point
  316.              (ZGCD-LIFT c f g vars vals degb)))))
  317.  
  318. ; ZGCD-LIFT returns objects called lifts.  These have the the following 
  319. ; structure
  320. ;      ((n <skel> <poly>) ...  )
  321. ; n corresponds to the degree in the main variable to which this guy 
  322. ; corresponds.
  323.  
  324. (defun ZGCD-LIFT (c f g vars vals degb)
  325.        (cond ((null vars)        ;No variables left, just the main one
  326.           (let ((p (lifting-factors-image c f g)))    ;Compute factor and 
  327.                     ;enforce leading coefficient
  328.            (if (pcoefp p) (throw 'relprime 1)    ;if the GCD is 1 quit
  329.                (do ((l (p-terms p) (pt-red l))    ;otherwise march
  330.                     ;though the polynomial
  331.                 (ans nil    ;constructing a lift for each term.
  332.                  (cons (list (pt-le l) '(nil) (list (pt-lc l)))
  333.                        ans)))
  334.                ((null l)
  335.                 (nreverse ans))))))
  336.          ((let ((prev-lift        ;Recurse if possible
  337.              (zgcd-lift (pcsubsty (car vals) (car vars) c)
  338.                 (pcsubsty (car vals) (car vars) f)
  339.                 (pcsubsty (car vals) (car vars) g)
  340.                 (cdr vars) (cdr vals) (cdr degb))))
  341.             (do ((i 0 (f1+ i))    ;counts to the degree bound
  342.              (lobjs (create-lobjs prev-lift)    ;need to create
  343.                     ;the appropriate matrices
  344.                 (clear-lobjs lobjs))    ;but reuse them at each
  345.                     ;step
  346.              (pts (add-point (list (car vals)))    ;List of random
  347.                   (add-point pts))    ;points
  348.              (linsols (mapcar 'make-linsols prev-lift)
  349.                   (merge-sol-lin
  350.                    linsols
  351.                    (sparse-lift
  352.                     (pcsubsty (car pts) (car vars) c)
  353.                     (pcsubsty (car pts) (car vars) f)
  354.                     (pcsubsty (car pts) (car vars) g)
  355.                     lobjs (cdr vars)))))
  356.             ((= i (car degb))
  357.              (interp-polys linsols (cdr pts) (car vars))))))))
  358.  
  359. (defun MAKE-LINSOLS (prev-lift)
  360.   (list (car prev-lift)
  361.     (cadr prev-lift)
  362.     (mapcan #'(lambda (q)
  363.             (cond ((pcoefp q) (list (list q)))
  364.               (t (do ((l (p-terms q) (pt-red l))
  365.                   (ans nil (cons (list (pt-lc l)) ans)))
  366.                  ((null l) ans)))))
  367.         (caddr prev-lift))))
  368.  
  369. (defun ADD-POINT (l)
  370.        (do ((try (cmod (random $pointbound))
  371.          (cmod (random $pointbound))))
  372.        ((null (zl-MEMBER try l))
  373.         (cons try l))))
  374.  
  375. (defun MERGE-SOL-LIN (l1 l2)
  376.        (do ((l l1 (cdr l))
  377.         (l2 l2 (cdr l2)))
  378.        ((null l) l1)
  379.        (cond ((= (caar l) (caar l2))
  380.           (rplaca (cddar l)
  381.               (mapcar 'cons (cadddr (cddar l2)) (caddar l)))))))
  382.  
  383. (defun INTERP-POLYS (l pts var)
  384.   (mapcar #'(lambda (q)
  385.           (cons (car q)
  386.             (new-skel
  387.              (cadr q)
  388.              (mapcar #'(lambda (r) (pinterp var pts r))
  389.                  (caddr q)))))
  390.       l))
  391.  
  392. (defun ZGCD (f g &aux $algebraic algfac*)
  393.    (let ((f (oldcontent f))            ;This is a good spot to
  394.      (g (oldcontent g))            ;initialize random
  395.      (gcd) (mon) 
  396.      (*which-factor*))
  397.  ;; *WHICH-FACTOR* is interpreted as follows.  It is set fairly deep in the
  398.  ;; algorithm, inside ZGCD1.
  399.  ;; 1 -> Lift the GCD
  400.  ;; 2 -> Lift the cofactor of F
  401.  ;; 3 -> Lift the cofactor of G
  402.  
  403.  
  404.        (setq mon (pgcd (car f) (car g))    ;compute GCD of content
  405.          f (cadr f) g (cadr g))    ;f and g are now primitive
  406.        (if (or (pcoefp f) (pcoefp g)
  407.           (not (eq (car f) (car g))))
  408.        (merror "Bad args to ZGCD"))
  409.        (ptimes mon
  410.            (do ((test))
  411.            (nil)
  412.            (setq gcd (catch 'relprime (zgcd1 f g)))
  413.            (setq test
  414.              (case *which-factor*
  415.                 (1 (testdivide f gcd))
  416.                 (2 (testdivide f gcd))
  417.                 (3 (testdivide g gcd))))
  418.            (cond ((not (null test))
  419.               (return
  420.                (cond ((equal *which-factor* 1)
  421.                   gcd)
  422.                  (t test))))
  423.              ((not (null modulus))
  424.               (return (let (($GCD '$RED))
  425.                     (pgcd f g)))))))))
  426.  
  427. (defun ZGCD1 (f g)
  428.    (let* ((modulus modulus)
  429.       first-lift
  430.       H degb c
  431.       (vars (sort (union1 (listovars f) (listovars g))
  432.                #'pointergp))
  433.       (GENVAR (REVERSE VARS))
  434.  
  435.  ;; the elements of the following degree vectors all correspond to the 
  436.  ;; contents of var.  Thus there may be variables missing that are in 
  437.  ;;GENVAR.
  438.  ;; (f-degv (zpdegreevector f vars))  ;;WHY NOT JUST PUT GENVAR THE REVERSE
  439.  ;; (g-degv (zpdegreevector g vars))  ;;THE REVERSE OF VARS AND JUST USE PDEGREEVECTOR--wfs
  440.       (F-DEGV (PDEGREEVECTOR F))
  441.       (G-DEGV (PDEGREEVECTOR G))
  442.       (gcd-degv (gcd-degree-vector f g vars)))
  443.  
  444. ;; First we try to decide which of the gcd and the cofactors of f and g 
  445. ;; is smallest.  The result of this decision is indicated by *which-factor*.
  446. ;; Then the leading coefficient that is to be enforced is changed if a 
  447. ;; cofactor has been chosen.
  448.     (case (setq *which-factor*
  449.              (determine-lifting-factor f-degv g-degv gcd-degv))
  450.            (1 (setq c (pgcd (p-lc f) (p-lc g))))
  451.            (2 (setq c (p-lc f)))
  452.            (3 (setq c (p-lc g))))
  453.  
  454.  ;; Next a degree bound must be chosen.
  455.     (setq degb
  456.           (reverse
  457.            (mapcar #'+
  458.                (case *which-factor*
  459.                   (1 gcd-degv)
  460.                   (2 (mapcar #'- f-degv gcd-degv))
  461.                   (3 (mapcar #'- g-degv gcd-degv)))
  462.                (zpdegreevector c vars))))
  463.  
  464.     (cond ((not (null modulus))
  465.            (lobj->poly (car vars) (cdr vars)
  466.         (zgcd-lift* c f g (cdr vars) (cdr degb))))
  467.           (t
  468.            (setq h (times (maxcoefficient f)
  469.                   (maxcoefficient g)))
  470.            (setq modulus *alpha)            ;Really should randomize
  471.            (setq first-lift
  472.              (zgcd-lift* (pmod c) (pmod f) (pmod g)
  473.                  (cdr vars) (cdr degb)))
  474.            (do ((linsols (mapcar #'(lambda (q)
  475.                      (cons (car q)
  476.                            (new-skel (cadr q) (caddr q))))
  477.                      first-lift)
  478.                  (merge-sol-lin-z linsols
  479.                           (sparse-lift cm fm gm lobjs (cdr vars))
  480.                           (times coef-bound
  481.                              (crecip (cmod coef-bound)))
  482.                           (times modulus coef-bound)))
  483.             (lobjs (create-lobjs first-lift)
  484.                (clear-lobjs lobjs))
  485.             (coef-bound *alpha (times modulus coef-bound))
  486.             (cm) (fm) (gm))
  487.            ((greaterp coef-bound H)
  488.             (setq modulus nil)
  489.             (lobj->poly (car vars) (cdr vars) linsols))
  490.            (setq modulus (newprime modulus))
  491.            (setq cm (pmod c)
  492.              fm (pmod f)
  493.              gm (pmod g)))))))
  494.  
  495. (defun LOBJ->POLY (var vars lobj)
  496.        (primpart
  497.     (cons var
  498.           (mapcan
  499.            #'(lambda (q) 
  500.             (list (car q)
  501.               (do ((x (cadr q) (cdr x))
  502.                    (y (caddr q) (cdr y))
  503.                    (ans 0
  504.                     (pplus ans
  505.                        (disrep-monom (cdar x) (car y)
  506.                              vars))))
  507.                   ((null x) ans))))
  508.            lobj))))
  509.  
  510. (defun DISREP-MONOM (monom c vars)
  511.        (cond ((null monom) c)
  512.          ((equal 0 (car monom))
  513.           (disrep-monom (cdr monom) c (cdr vars)))
  514.          ((list (car vars) (car monom)
  515.             (disrep-monom (cdr monom) c (cdr vars))))))
  516.  
  517. (defun MERGE-SOL-LIN-Z (l1 l2 c new-coef-bound)
  518.        (do ((l l1 (cdr l))
  519.         (l2 l2 (cdr l2))
  520.         (modulus new-coef-bound)
  521.         (n))
  522.        ((null l) l1)
  523.        (cond ((= (caar l) (caar l2))
  524.           (rplaca (cddar l)
  525.            (mapcar
  526.             #'(lambda (a b)
  527.               (cond ((greaterp
  528.                   (abs
  529.                    (setq n
  530.                      (cplus b (ctimes c (cdifference a b)))))
  531.                   new-coef-bound)
  532.                  (throw 'relprime 1))
  533.                 (n)))
  534.                (cadddr (cddar l2)) (caddar l)))))))
  535.  
  536. ;; The following function tries to determine the degree of gcd(f, g) in each
  537. ;; variable.  This is done in the following manner:  All but one of the
  538. ;; variables in f and g are replaced by randomly chosen integers.  The
  539. ;; resulting polynomials are called f* and g*.   The degree of gcd(f*, g*) is
  540. ;; used as the degree of gcd(f, g) in that variable.
  541. ;;
  542. ;; The univariate gcd's are computed with modulus=*alpha.
  543.  
  544. (defun GCD-DEGREE-VECTOR (f g vars)
  545.    (let ((modulus *alpha))
  546.      (setq f (pmod f) g (pmod g))
  547.      (do ((vn (cdr vars) (cdr vn))
  548.       (vs (zl-DELETE (car vars) (copy1 vars))
  549.           (zl-DELETE (car vn) (copy1 vars)))
  550.       (l) (f*) (g*) (gcd*) (rand))
  551.      (nil)
  552.      (setq rand (gen-point vs))
  553.      (setq f* (pcsub f rand vs)
  554.            g* (pcsub g rand vs))
  555.      (cond ((or (pcoefp f*) (pcoefp g*)
  556.             (pcoefp (setq gcd* (pgcdu f* g*))))
  557.         (push 0 l))
  558.            (t (push (pt-le (p-terms gcd*)) l)))
  559.      (cond ((null vn)
  560.         (return l))))))        ;No reverse needed here
  561.  
  562. ; DETERMINE-LIFTING-FACTOR returns a number indicating which factor of f or g
  563. ; to which to lift 
  564.  
  565. (defun dlf-mumblify (a b)
  566.   (sloop for x in a for y in b sum (difference x y)))
  567.  
  568. (defun DETERMINE-LIFTING-FACTOR (f-degv g-degv gcd-degv)
  569.   (let* ((fv ;(apply '+ (mapcar '- f-degv gcd-degv))
  570.          (dlf-mumblify f-degv gcd-degv))
  571.      (gv ;(apply '+ (mapcar '- g-degv gcd-degv))
  572.          (dlf-mumblify g-degv gcd-degv))
  573.      (gcdv (apply '+ gcd-degv)))
  574.     (if (lessp fv gcdv)
  575.     (if (lessp fv gv) 2 3)
  576.     (if (lessp gv gcdv) 3 1))))
  577. ;(defun DETERMINE-LIFTING-FACTOR (f-degv g-degv gcd-degv)
  578. ;       (let* ((fv (apply '+ (mapcar '- f-degv gcd-degv)))
  579. ;          (gv (apply '+ (mapcar '- g-degv gcd-degv)))
  580. ;          (gcdv (apply '+ gcd-degv)))
  581. ;         (if (lessp fv gcdv)
  582. ;         (if (lessp fv gv) 2 3)
  583. ;         (if (lessp gv gcdv) 3 1))))
  584.   
  585.  
  586. (defun EXCISE-EXTRA-VARIABLES (degv vars)
  587.        (do ((l (reverse degv) (cdr l))
  588.         (lv (reverse genvar) (cdr lv))
  589.         (ndegv))
  590.        ((null l)
  591.         ndegv)
  592.        (cond ((eq (car lv) (car vars))
  593.           (push (car l) ndegv)
  594.           (setq vars (cdr vars))))))
  595.  
  596. (defun ZPDEGREEVECTOR (p vars)
  597.        (excise-extra-variables (pdegreevector p) vars))
  598.  
  599. ;; Local Modes:
  600. ;; Mode:LISP
  601. ;; Fill Column:76
  602. ;; Auto Fill Mode:1
  603. ;; Comment Column:40
  604. ;; END:
  605.